package com.creditease.mobile.util;

import android.graphics.drawable.Drawable;
import android.os.Handler;

import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class AsyncImageLoader3 {
    // 为了加快速度，在内存中开启缓存（主要应用于重复图片较多时，或者同一个图片要多次被访问，比如在ListView时来回滚动）
    public Map<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();

    private ExecutorService executorService = Executors.newFixedThreadPool(5); // 固定五个线程来执行任务
    private final Handler handler = new Handler();

    /**
     * @param imageUrl 图像url地址
     * @param callback 回调接口
     * @return 返回内存中缓存的图像，第一次加载返回null
     */
    public Drawable loadDrawable(final String imageUrl, final ImageCallback callback) {
        // 如果缓存过就从缓存中取出数据
        if (imageCache.containsKey(imageUrl)) {
            SoftReference<Drawable> softReference = imageCache.get(imageUrl);
            if (softReference.get() != null) {
                return softReference.get();
            }
        }
        // 缓存中没有图像，则从网络上取出数据，并将取出的数据缓存到内存中
        Future<Drawable> future = executorService.submit(new Callable<Drawable>() {

            @Override
            public Drawable call() throws Exception {
                try {
                    final Drawable drawable = loadImageFromUrl(imageUrl);
                    imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
                    handler.post(new Runnable() {
                        public void run() {
                            callback.imageLoaded(drawable);
                        }
                    });
                    return drawable;
                } catch (Exception e) {
                    e.printStackTrace();
                    throw e;
                }
            }
        });

        return null;
    }

    // 从网络上取数据方法 new URL(imageUrl).openStream()
    protected Drawable loadImageFromUrl(String imageUrl) throws IOException {
        try {
            // 测试时，模拟网络延时，实际时这行代码不能有
            // SystemClock.sleep(2000);
            InputStream is = HttpUtils.getHttpStream(imageUrl);
            if (is != null) {
                String fileName = FileUtil.getFileName(imageUrl);
                return Drawable.createFromStream(is, fileName);
            }
            return null;
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }
    }

    // 对外界开放的回调接口
    public interface ImageCallback {
        // 注意 此方法是用来设置目标对象的图像资源
        public void imageLoaded(Drawable imageDrawable);
    }
}